import 'package:flutter/foundation.dart';
import '../../domain/entities/todo.dart' as entity;
import '../../domain/entities/todo_request.dart' as entity_request;
import '../../domain/entities/project.dart' as entity_project;
import '../../domain/repositories/todo_repository.dart' as domain_todo; // 导入domain层接口
import '../datasources/local/local_data_source.dart';
import '../datasources/remote/todo_api_service.dart';
import '../models/todo_model.dart' as model;
import '../../core/offline/offline_mode_manager.dart';
import '../../core/offline/offline_data_manager.dart';

/// 待办仓库实现
class TodoRepositoryImpl implements domain_todo.TodoRepository {
  final TodoApiService _apiService;
  final LocalDataSource _localDataSource;
  final OfflineModeManager _offlineModeManager;
  final OfflineDataManager _offlineDataManager;

  TodoRepositoryImpl({
    required TodoApiService apiService,
    required LocalDataSource localDataSource,
    required OfflineModeManager offlineModeManager,
    required OfflineDataManager offlineDataManager,
  })  : _apiService = apiService,
        _localDataSource = localDataSource,
        _offlineModeManager = offlineModeManager,
        _offlineDataManager = offlineDataManager;

  @override
  Future<List<entity.Todo>> getTodos({
    int? projectId,
    entity.TodoStatus? status,
    int? assigneeId,
    DateTime? dueDateFrom,
    DateTime? dueDateTo,
  }) async {
    try {
      if (_offlineModeManager.currentStatus == OfflineModeStatus.offline) {
        // 离线模式：从本地数据库获取数据
        final localTodos = await _localDataSource.getTodos(
          projectId: projectId,
          status: status != null ? _mapStatusToModel(status) : null,
          assigneeId: assigneeId,
        );
        return localTodos.map((todoModel) => _mapToEntity(todoModel)).toList();
      }

      // 在线模式：从API获取数据
      final response = await _apiService.getTodos(
        projectId: projectId,
        status: status != null ? _mapStatusToModelEntity(status) : null,
        assigneeId: assigneeId,
        dueDateFrom: dueDateFrom,
        dueDateTo: dueDateTo,
      );

      if (response.success && response.data != null) {
        // 更新本地数据库
        for (final todoModel in response.data!) {
          await _localDataSource.saveTodo(todoModel);
        }
        return response.data!
            .map((todoModel) => _mapToEntity(todoModel))
            .toList();
      } else {
        throw Exception(response.message ?? '获取待办任务列表失败');
      }
    } catch (e) {
      // 如果在线模式失败，尝试从本地获取数据
      if (_offlineModeManager.canPerformOfflineOperation()) {
        final localTodos = await _localDataSource.getTodos(
          projectId: projectId,
          status: status != null ? _mapStatusToModel(status) : null,
          assigneeId: assigneeId,
        );
        return localTodos.map((todoModel) => _mapToEntity(todoModel)).toList();
      }
      rethrow;
    }
  }

  @override
  Future<entity.Todo> getTodo(int todoId) async {
    try {
      if (_offlineModeManager.currentStatus == OfflineModeStatus.offline) {
        // 离线模式：从本地数据库获取数据
        final localTodo = await _localDataSource.findTodoById(todoId);
        if (localTodo == null) {
          throw Exception('待办任务不存在');
        }
        return _mapToEntity(localTodo);
      }

      // 在线模式：从API获取数据
      final response = await _apiService.getTodo(todoId);

      if (response.success && response.data != null) {
        // 更新本地数据库
        await _localDataSource.saveTodo(response.data!);
        return _mapToEntity(response.data!);
      } else {
        throw Exception(response.message ?? '获取待办任务详情失败');
      }
    } catch (e) {
      // 如果在线模式失败，尝试从本地获取数据
      if (_offlineModeManager.canPerformOfflineOperation()) {
        final localTodo = await _localDataSource.findTodoById(todoId);
        if (localTodo == null) {
          throw Exception('待办任务不存在');
        }
        return _mapToEntity(localTodo);
      }
      rethrow;
    }
  }

  @override
  Future<entity.Todo> createTodo(
      entity_request.TodoCreateRequest request) async {
    try {
      if (_offlineModeManager.canPerformOfflineOperation()) {
        // 离线模式：记录离线操作并保存到本地数据库
        // 注意：model.TodoCreateRequest中的projectId是必需的，而entity.TodoCreateRequest中的projectId是可选的
        await _offlineDataManager
            .createTodoOfflineOperation(model.TodoCreateRequest(
          projectId: request.projectId ?? 0, // 提供默认值
          title: request.title,
          description: request.description,
          priority: _mapPriorityToModel(request.priority),
          todoType: _mapTodoTypeToModel(request.todoType),
          assigneeId: request.assigneeId,
          dueDate: request.dueDate,
          estimatedHours: request.estimatedHours,
        ));

        // 创建本地待办任务模型
        final localTodoModel = model.TodoModel(
          id: DateTime.now().millisecondsSinceEpoch, // 使用时间戳作为临时ID
          projectId: request.projectId ?? 0, // 提供默认值
          title: request.title,
          description: request.description,
          status: model.TodoStatus.todo,
          priority: _mapPriorityToModel(request.priority),
          todoType: _mapTodoTypeToModel(request.todoType),
          reporterId: 0, // 临时值
          assigneeId: request.assigneeId,
          createTime: DateTime.now(),
          updateTime: DateTime.now(),
          dueDate: request.dueDate,
          estimatedHours: request.estimatedHours,
          actualHours: 0.0,
        );

        // 保存到本地数据库
        await _localDataSource.saveTodo(localTodoModel);

        return _mapToEntity(localTodoModel);
      }

      // 在线模式：调用API创建待办任务
      // 注意：model.TodoCreateRequest中的projectId是必需的，而entity.TodoCreateRequest中的projectId是可选的
      final apiRequest = model.TodoCreateRequest(
        projectId: request.projectId ?? 0, // 提供默认值
        title: request.title,
        description: request.description,
        priority: _mapPriorityToModel(request.priority),
        todoType: _mapTodoTypeToModel(request.todoType),
        assigneeId: request.assigneeId,
        dueDate: request.dueDate,
        estimatedHours: request.estimatedHours,
      );

      final response = await _apiService.createTodo(apiRequest);

      if (response.success && response.data != null) {
        // 更新本地数据库
        await _localDataSource.saveTodo(response.data!);
        return _mapToEntity(response.data!);
      } else {
        throw Exception(response.message ?? '创建待办任务失败');
      }
    } catch (e) {
      debugPrint('创建待办任务失败: $e');
      rethrow;
    }
  }

  @override
  Future<entity.Todo> updateTodo(
      int todoId, entity_request.TodoUpdateRequest request) async {
    try {
      if (_offlineModeManager.canPerformOfflineOperation()) {
        // 离线模式：记录离线操作并更新本地数据库
        await _offlineDataManager.updateTodoOfflineOperation(
            todoId,
            model.TodoUpdateRequest(
              title: request.title,
              description: request.description,
              status: request.status != null
                  ? _mapStatusToModel(request.status!)
                  : null,
              priority: request.priority != null
                  ? _mapPriorityToModel(request.priority!)
                  : null,
              todoType: request.todoType != null
                  ? _mapTodoTypeToModel(request.todoType!)
                  : null,
              assigneeId: request.assigneeId,
              dueDate: request.dueDate,
              estimatedHours: request.estimatedHours,
              actualHours: request.actualHours,
            ));

        // 更新本地数据库中的待办任务
        final existingTodo = await _localDataSource.findTodoById(todoId);
        if (existingTodo == null) {
          throw Exception('待办任务不存在');
        }

        final updatedTodo = existingTodo.copyWith(
          title: request.title ?? existingTodo.title,
          description: request.description ?? existingTodo.description,
          status: request.status != null
              ? _mapStatusToModel(request.status!)
              : existingTodo.status,
          priority: request.priority != null
              ? _mapPriorityToModel(request.priority!)
              : existingTodo.priority,
          todoType: request.todoType != null
              ? _mapTodoTypeToModel(request.todoType!)
              : existingTodo.todoType,
          dueDate: request.dueDate ?? existingTodo.dueDate,
          estimatedHours: request.estimatedHours ?? existingTodo.estimatedHours,
          actualHours: request.actualHours ?? existingTodo.actualHours,
          updateTime: DateTime.now(),
        );

        await _localDataSource.saveTodo(updatedTodo);

        return _mapToEntity(updatedTodo);
      }

      // 在线模式：调用API更新待办任务
      final apiRequest = model.TodoUpdateRequest(
        title: request.title,
        description: request.description,
        status:
            request.status != null ? _mapStatusToModel(request.status!) : null,
        priority: request.priority != null
            ? _mapPriorityToModel(request.priority!)
            : null,
        todoType: request.todoType != null
            ? _mapTodoTypeToModel(request.todoType!)
            : null,
        assigneeId: request.assigneeId,
        dueDate: request.dueDate,
        estimatedHours: request.estimatedHours,
        actualHours: request.actualHours,
      );

      final response = await _apiService.updateTodo(todoId, apiRequest);

      if (response.success && response.data != null) {
        // 更新本地数据库
        await _localDataSource.saveTodo(response.data!);
        return _mapToEntity(response.data!);
      } else {
        throw Exception(response.message ?? '更新待办任务失败');
      }
    } catch (e) {
      debugPrint('更新待办任务失败: $e');
      rethrow;
    }
  }

  @override
  Future<void> deleteTodo(int todoId) async {
    try {
      if (_offlineModeManager.canPerformOfflineOperation()) {
        // 离线模式：记录离线操作并从本地数据库删除
        await _offlineDataManager.deleteTodoOfflineOperation(todoId);
        await _localDataSource.deleteTodo(todoId);
        return;
      }

      // 在线模式：调用API删除待办任务
      final response = await _apiService.deleteTodo(todoId);

      if (response.success) {
        // 更新本地数据库
        await _localDataSource.deleteTodo(todoId);
      } else {
        throw Exception(response.message ?? '删除待办任务失败');
      }
    } catch (e) {
      debugPrint('删除待办任务失败: $e');
      rethrow;
    }
  }

  @override
  Future<List<entity.Todo>> getProjectTodos(int projectId) async {
    try {
      if (_offlineModeManager.currentStatus == OfflineModeStatus.offline) {
        // 离线模式：从本地数据库获取数据
        final localTodos =
            await _localDataSource.getTodosByProjectId(projectId);
        return localTodos.map((todoModel) => _mapToEntity(todoModel)).toList();
      }

      // 在线模式：从API获取数据
      final response = await _apiService.getProjectTodos(projectId);

      if (response.success && response.data != null) {
        // 更新本地数据库
        for (final todoModel in response.data!) {
          await _localDataSource.saveTodo(todoModel);
        }
        return Future.value(response.data!
            .map((todoModel) => _mapToEntity(todoModel))
            .toList());
      } else {
        throw Exception(response.message ?? '获取项目待办任务列表失败');
      }
    } catch (e) {
      // 如果在线模式失败，尝试从本地获取数据
      if (_offlineModeManager.canPerformOfflineOperation()) {
        final localTodos =
            await _localDataSource.getTodosByProjectId(projectId);
        return Future.value(
            localTodos.map((todoModel) => _mapToEntity(todoModel)).toList());
      }
      rethrow;
    }
  }

  @override
  Future<List<entity.Todo>> getMyTodos() async {
    try {
      if (_offlineModeManager.currentStatus == OfflineModeStatus.offline) {
        // 离线模式：从本地数据库获取数据
        final localTodos = await _localDataSource.getMyTodos();
        return localTodos.map((todoModel) => _mapToEntity(todoModel)).toList();
      }

      // 在线模式：从API获取数据
      final response = await _apiService.getMyTodos();

      if (response.success && response.data != null) {
        // 更新本地数据库
        for (final todoModel in response.data!) {
          await _localDataSource.saveTodo(todoModel);
        }
        return Future.value(response.data!
            .map((todoModel) => _mapToEntity(todoModel))
            .toList());
      } else {
        throw Exception(response.message ?? '获取我的待办任务列表失败');
      }
    } catch (e) {
      // 如果在线模式失败，尝试从本地获取数据
      if (_offlineModeManager.canPerformOfflineOperation()) {
        final localTodos = await _localDataSource.getMyTodos();
        return Future.value(
            localTodos.map((todoModel) => _mapToEntity(todoModel)).toList());
      }
      rethrow;
    }
  }

  /// 将实体状态映射到模型状态
  model.TodoStatus _mapStatusToModel(entity.TodoStatus status) {
    switch (status) {
      case entity.TodoStatus.todo:
        return model.TodoStatus.todo;
      case entity.TodoStatus.inProgress:
        return model.TodoStatus.inProgress;
      case entity.TodoStatus.done:
        return model.TodoStatus.done;
      case entity.TodoStatus.blocked:
        return model.TodoStatus.blocked;
      default:
        return model.TodoStatus.todo;
    }
  }

  /// 将模型状态映射到实体状态
  entity.TodoStatus _mapStatusToEntity(model.TodoStatus status) {
    switch (status) {
      case model.TodoStatus.todo:
        return entity.TodoStatus.todo;
      case model.TodoStatus.inProgress:
        return entity.TodoStatus.inProgress;
      case model.TodoStatus.done:
        return entity.TodoStatus.done;
      case model.TodoStatus.blocked:
        return entity.TodoStatus.blocked;
      default:
        return entity.TodoStatus.todo;
    }
  }

  /// 将实体状态映射到API请求状态
  model.TodoStatus? _mapStatusToModelEntity(entity.TodoStatus? status) {
    if (status == null) return null;
    switch (status) {
      case entity.TodoStatus.todo:
        return model.TodoStatus.todo;
      case entity.TodoStatus.inProgress:
        return model.TodoStatus.inProgress;
      case entity.TodoStatus.done:
        return model.TodoStatus.done;
      case entity.TodoStatus.blocked:
        return model.TodoStatus.blocked;
      default:
        return model.TodoStatus.todo;
    }
  }

  /// 将实体优先级映射到模型优先级
  model.Priority _mapPriorityToModel(entity_project.Priority priority) {
    switch (priority) {
      case entity_project.Priority.high:
        return model.Priority.high;
      case entity_project.Priority.medium:
        return model.Priority.medium;
      case entity_project.Priority.low:
        return model.Priority.low;
      default:
        return model.Priority.medium;
    }
  }

  /// 将模型优先级映射到实体优先级
  entity_project.Priority _mapPriorityToEntity(model.Priority priority) {
    switch (priority) {
      case model.Priority.high:
        return entity_project.Priority.high;
      case model.Priority.medium:
        return entity_project.Priority.medium;
      case model.Priority.low:
        return entity_project.Priority.low;
      default:
        return entity_project.Priority.medium;
    }
  }

  /// 将实体任务类型映射到模型任务类型
  model.TodoType _mapTodoTypeToModel(entity.TodoType todoType) {
    switch (todoType) {
      case entity.TodoType.communication:
        return model.TodoType.communication;
      case entity.TodoType.schedule:
        return model.TodoType.schedule;
      case entity.TodoType.document:
        return model.TodoType.document;
      case entity.TodoType.dataSource:
        return model.TodoType.dataSource;
      case entity.TodoType.develop:
        return model.TodoType.develop;
      case entity.TodoType.test:
        return model.TodoType.test;
      case entity.TodoType.uat:
        return model.TodoType.uat;
      case entity.TodoType.release:
        return model.TodoType.release;
      default:
        return model.TodoType.develop;
    }
  }

  /// 将模型任务类型映射到实体任务类型
  entity.TodoType _mapTodoTypeToEntity(model.TodoType todoType) {
    switch (todoType) {
      case model.TodoType.communication:
        return entity.TodoType.communication;
      case model.TodoType.schedule:
        return entity.TodoType.schedule;
      case model.TodoType.document:
        return entity.TodoType.document;
      case model.TodoType.dataSource:
        return entity.TodoType.dataSource;
      case model.TodoType.develop:
        return entity.TodoType.develop;
      case model.TodoType.test:
        return entity.TodoType.test;
      case model.TodoType.uat:
        return entity.TodoType.uat;
      case model.TodoType.release:
        return entity.TodoType.release;
      default:
        return entity.TodoType.develop;
    }
  }

  /// 将模型转换为实体
  entity.Todo _mapToEntity(model.TodoModel model) {
    return entity.Todo(
      id: model.id,
      projectId: model.projectId,
      projectName: model.projectName ?? '',
      title: model.title,
      description: model.description,
      status: _mapStatusToEntity(model.status),
      priority: _mapPriorityToEntity(model.priority),
      todoType: _mapTodoTypeToEntity(model.todoType),
      assigneeName: model.assigneeName,
      reporterName: model.reporterName ?? '',
      dueDate: model.dueDate,
      estimatedHours: model.estimatedHours,
      actualHours: model.actualHours,
      createTime: model.createTime,
      updateTime: model.updateTime ?? model.createTime,
      isNearDeadline: model.isOverdue,
    );
  }
}